package com.gxd.commons.utils;

import com.gxd.commons.constants.ExceptionConstant;
import com.gxd.commons.exception.ToolException;
import org.apache.commons.lang3.StringUtils;


import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.gxd.commons.constants.SendMailConstant;
import com.gxd.commons.entity.SendMailFileRequest;

public class SendmailUtil {

    // 设置服务器
    private static String keySmtp = SendMailConstant.KEY_SMTP;
    private static String valueSmtp = SendMailConstant.VALUE_SMTP;
    // 服务器验证
    private static String keyProps = SendMailConstant.KEY_PROPS;
    private static String valueProps = SendMailConstant.VALUE_PROPS;
    // 发件人用户名、密码
    private String sendUser = SendMailConstant.SEND_USER;
    private String sendUname = SendMailConstant.SEND_UNAME;
    private String sendPwd = SendMailConstant.SEND_PWD;
    // 建立会话
    private MimeMessage message;
    private Session s;

    public static SendmailUtil smu = new SendmailUtil();

    /*
     * 初始化方法
     */
    public SendmailUtil() {
        //
    }

    /**
     * 获取message 
     * @param sName 发件人账号
     * @param sPwd 发件人密码
     */
    public void initMessage(String sName, String sPwd) {
        sendUser = sName;
        sendUname = sName;
        sendPwd = sPwd;
        String mark = initValueSmtp(sName);
        Properties props = new Properties();
        props.setProperty(keySmtp, valueSmtp);
        props.put(keyProps, valueProps);
        props.put(keyProps, valueProps);
        if ("qq".equals(mark)) { // qq邮箱需要ssl
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.port", "465");
        }
        s = Session.getDefaultInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(sendUname, sendPwd);
            }
        });
        s.setDebug(true);
        message = new MimeMessage(s);
    }

    /**
     * 初始化smtp服务器
     * @param sName
     */
    public String initValueSmtp(String sName) {
        // 根据发送邮箱的账号解析出smtp服务器
        int fromIndex = sName.indexOf("@") + 1;
        String str = sName.substring(fromIndex);
        int toIndex = str.indexOf(".");
        String mark = str.substring(0, toIndex);
        // 支持163,qq,sina邮箱
        if ("163".equals(mark) || "qq".equals(mark) || "sina".equals(mark)) {
            valueSmtp = "smtp." + sName.split("@")[1];
        } else {
            valueSmtp = SendMailConstant.VALUE_SMTP;
        }
        return mark;

    }

    /**
     * 
     * @param toUser 多个收件人
     * @param ccUser 多个抄送人
     * @param bccUser 多个密送人
     * @param sendUser 发件人
     * @param sendPwd 发件人密码
     * @param title 邮件主题
     * @param content 邮件内容
     * @return
     * @throws Exception
     */
    public static void sendMail(String[] toUser, String[] ccUser, String[] bccUser, String sendUser, String sendPwd, String title,
        String content, List<SendMailFileRequest> sendMailFileRequestList) throws Exception {
        // 获取message
        smu.initMessage(sendUser, sendPwd);
        // 返回的结果集
        smu.doSendHtmlEmail(toUser, ccUser, bccUser, title, content, sendMailFileRequestList); // 发送邮件

    }

    /**
     * 发送邮件详细
     * @param toUser 
     * @param ccUser
     * @param bccUser
     * @param title
     * @param content
     * @throws Exception
     */
    public void doSendHtmlEmail(String[] toUser, String[] ccUser, String[] bccUser, String title, String content,
        List<SendMailFileRequest> sendMailFileRequestList) throws Exception {
        // 发件人
        InternetAddress from = new InternetAddress(sendUser);
        message.setFrom(from);
        // 设置多个收件人
        if (toUser != null && toUser.length > 0) {
            List<InternetAddress> addresses = new ArrayList<InternetAddress>();
            for (String to : toUser) {
                if (StringUtils.isEmpty(to)) {
                    continue;
                }
                addresses.add(new InternetAddress(to));
            }
            if (!(addresses.size() > 0)) {
                throw new ToolException(ExceptionConstant.NO_TO_USER.getValue(), ExceptionConstant.NO_TO_USER.getMsg());
            }
            message.setRecipients(Message.RecipientType.TO, addresses.toArray(new InternetAddress[addresses.size()]));
        } else {
            throw new ToolException(ExceptionConstant.NO_TO_USER.getValue(), ExceptionConstant.NO_TO_USER.getMsg());
        }
        // 设置多个抄送地址
        if (ccUser != null && ccUser.length > 0) {
            List<InternetAddress> ccAddresses = new ArrayList<InternetAddress>();
            for (String cc : ccUser) {
                if (StringUtils.isEmpty(cc)) {
                    continue;
                }
                ccAddresses.add(new InternetAddress(cc));
            }
            message.setRecipients(Message.RecipientType.CC, ccAddresses.toArray(new InternetAddress[ccAddresses.size()]));
        }
        // 设置多个密送地址
        if (bccUser != null && bccUser.length > 0) {
            List<InternetAddress> bccAddresses = new ArrayList<InternetAddress>();
            for (String bcc : bccUser) {
                if (StringUtils.isEmpty(bcc)) {
                    continue;
                }
                bccAddresses.add(new InternetAddress(bcc));
            }
            message.setRecipients(Message.RecipientType.BCC, bccAddresses.toArray(new InternetAddress[bccAddresses.size()]));
        }
        // 邮件标题
        message.setSubject(title);
        // 邮件组合为混合模式
        MimeMultipart multipart = new MimeMultipart("mixed");
        // 邮件正文
        MimeBodyPart bodyPart = new MimeBodyPart();
        bodyPart.setContent(content, "text/html;charset=GBK");
        multipart.addBodyPart(bodyPart);
        // 内嵌图片
        // 添加附件
        try {
            if (sendMailFileRequestList != null && sendMailFileRequestList.size() > 0) {
                for (SendMailFileRequest sendMailFileRequest : sendMailFileRequestList) {
                    if (StringUtils.isNotEmpty(sendMailFileRequest.getFilePaths())
                        && StringUtils.isNotEmpty(sendMailFileRequest.getShowNames())) {
                        bodyPart = new MimeBodyPart();
                        InputStream is = new URL(sendMailFileRequest.getFilePaths()).openConnection().getInputStream();
                        DataSource dataSource = new ByteArrayDataSource(is, "application/png");
                        DataHandler dataHandler = new DataHandler(dataSource);
                        bodyPart.setDataHandler(dataHandler);
                        bodyPart.setFileName(MimeUtility.encodeText(sendMailFileRequest.getShowNames()));
                        multipart.addBodyPart(bodyPart);
                    }
                }
            }
        } catch (Exception e) {
            throw new ToolException(ExceptionConstant.ERROR_FILE_PATH.getValue(), ExceptionConstant.ERROR_FILE_PATH.getMsg());
        }
        message.setContent(multipart);
        message.saveChanges();
        Transport transport = s.getTransport("smtp");
        // smtp验证，就是你用来发邮件的邮箱用户名密码
        try {
            transport.connect(valueSmtp, sendUname, sendPwd);
        } catch (Exception e) {
            throw new ToolException(ExceptionConstant.ERROR_SEND_PWDH.getValue(), ExceptionConstant.ERROR_SEND_PWDH.getMsg());
        }
        // 发送
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();

    }

}
